//go:build windows
// +build windows

package panicsafe

import (
	"os"
	"syscall"
	"unsafe"
)

var (
	kernel32         = syscall.MustLoadDLL("kernel32.dll")
	procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)

func setStdHandle(stdhandle int32, handle syscall.Handle) error {
	r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
	if r0 == 0 {
		if e1 != 0 {
			return error(e1)
		}
		return syscall.EINVAL
	}
	return nil
}

// redirectStderr to the file passed in
func RedirectStderr(f *os.File, msg string) error {
	err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
	if err != nil {
		// log.Fatalf("Failed to redirect stderr to file: %v, msg:%s", err, msg)
		return err
	}
	// SetStdHandle does not affect prior references to stderr
	os.Stderr = f
	return nil
}

// disk usage of path/disk
func DiskUsage(path string) (disk DiskStatus, err error) {
	c := kernel32.MustFindProc("GetDiskFreeSpaceExW")
	lpFreeBytesAvailable := int64(0)
	lpTotalNumberOfBytes := int64(0)
	lpTotalNumberOfFreeBytes := int64(0)
	ptr, er := syscall.UTF16PtrFromString(path)
	if er != nil {
		return disk, er
	}

	r2, _, er := c.Call(uintptr(unsafe.Pointer(ptr)),
		uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
		uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
		uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
	if uint(r2) == 1 {
		disk.All = uint64(lpTotalNumberOfBytes)
		disk.Free = uint64(lpFreeBytesAvailable)
		disk.Used = disk.All - disk.Free
	} else {
		err = er
	}

	return
}
